﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _05_Thread_线程练习_1
{
    public partial class Form1 : Form
    {
        Random rd = new Random();

        List<ThreadClass> threadClasses = new List<ThreadClass>();


        public Form1()
        {
            InitializeComponent();
            //取消跨线程访问检查
            CheckForIllegalCrossThreadCalls = false;

            for (int i = 1; i <= 5; i++)
            {
                //实例化线程对象
                ThreadClass threadClass = new ThreadClass();
                //设置对象名称
                threadClass.Name = "线程-" + i;

                //查找指定的控件(启动与挂起按钮)
                Button btnStart = this.tableLayoutPanel1.Controls.Find("BtnStart" + i, true)[0] as Button;
                Button btnReset = this.tableLayoutPanel1.Controls.Find("BtnReset" + i, true)[0] as Button;
                //查找指定的控件(进度条与百分比标签)
                ProgressBar progressBar = this.tableLayoutPanel1.Controls.Find("ProgressBar" + i, true)[0] as ProgressBar;
                Label label = this.tableLayoutPanel1.Controls.Find("Value" + i, true)[0] as Label;
                //当程序运行起来后,线程运行时,更新进度条与label标签
                threadClass.RunEvent += Value => 
                {
                    progressBar.Value = Value;
                    label.Text = Value + "%";
                    //返回延时时间
                    if (this.radioButton1.Checked)
                    {
                        //设置延时时间
                        return int.Parse(this.textBox1.Text);
                    }
                    else
                    {
                        //延时时间
                        return rd.Next(int.Parse(this.textBox2.Text), int.Parse(this.textBox3.Text));
                    }

                };

                btnStart.Click += (s, e) =>
                {
                    if (btnStart.Text == "启 动")
                    {
                        threadClass.Strart();
                    }
                    else
                    {
                        threadClass.Abort();
                    }
                };

                btnReset.Click += (s, e) => 
                {
                    if (btnReset.Text == "挂 起")
                    {
                        threadClass.Suspend();
                    }
                    else
                    {
                        threadClass.Resume();
                    }
                };

                //启动与停止，响应事件
                threadClass.StartAndAbortEvent += () => 
                {
                    btnReset.Enabled = btnStart.Text == "启 动" ? true : false;
                    btnStart.Text = btnStart.Text == "启 动" ? "停 止" : "启 动";                    
                };

                //挂起与唤醒，响应事件
                threadClass.SuspendAndResumeEvent += () => 
                {
                    btnStart.Enabled = btnReset.Text == "挂 起" ? false : true;
                    btnReset.Text = btnReset.Text == "挂 起" ? "唤 醒" : "挂 起";                    
                };

                threadClasses.Add(threadClass);
            }

            foreach (Button btn in this.groupBox1.Controls)
            {
                if (btn.Text == "线程启动") btn.Click += (s,e)=> threadClasses.ForEach(t => t.Strart());
                if (btn.Text == "线程挂起") btn.Click += (s, e) => threadClasses.ForEach(t => t.Suspend());
                if (btn.Text == "线程唤醒") btn.Click += (s, e) => threadClasses.ForEach(t => t.Resume());
                if (btn.Text == "线程终止") btn.Click += (s, e) => threadClasses.ForEach(t => t.Abort());
                if (btn.Text == "清空进度条") btn.Click += (s, e) => ClearProgressBar();
            }


        }


        public void ClearProgressBar()
        {
            for (int i = 1; i <= 5; i++)
            {
                ProgressBar progressBar = this.tableLayoutPanel1.Controls.Find("progressBar" + i, true)[0] as ProgressBar;
                progressBar.Value = 0;
                Label label = this.tableLayoutPanel1.Controls.Find("Value" + i, true)[0] as Label;
                label.Text = "0%";
            }

        }
        /// <summary>
        /// 同步到达
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //获取线程当中进度最快
            int max = threadClasses.Max(t => t.Value);
            //将进度最快的线程挂起
            threadClasses.Find(t => t.Value == max).Suspend();
            //启动一个线程专门用来监控，如果其他线程到达最快的进度，就将其挂起
            new Thread(() => 
            {
                do
                {

                    //循环检测集合中的所有对象，如果大于或等于最大值那么挂起
                    threadClasses.FindAll(t => t.Value > max).ForEach(t => t.Suspend());
                    //延时等待，防止CPU跑过快
                    Thread.Sleep(100);
                    //判断如何集合当中全部挂起说明已经不用再检测，直接退出当前循环
                } while (threadClasses.FindAll(t=>t.theState==threadState.Join).Count != threadClasses.Count);

                Thread.Sleep(250);

                //设置为相同延时
                this.radioButton1.Checked = true;

                if (((Button)sender).Text == "同步到达")
                {
                    //同步唤醒线程
                    threadClasses.ForEach(t => t.Resume());
                }
                else
                {
                    foreach (string item in this.listBox1.Items)
                    {
                        threadClasses.Find(t => t.Name == item).Resume();
                        Thread.Sleep(int.Parse(this.textBox4.Text));
                    }
                }
            }) { IsBackground = true }.Start();
        }
    }
}
